package org.graduation.IM.service.socket;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.corundumstudio.socketio.SocketIOClient;
import org.graduation.IM.mapper.FriendsMapper;
import org.graduation.IM.mapper.GroupMessageMapper;
import org.graduation.IM.mapper.MessageMapper;
import org.graduation.feignapi.ProjectClient;
import org.graduation.model.common.IM.Friends;
import org.graduation.model.common.IM.GroupMessage;
import org.graduation.model.common.IM.Message;
import org.graduation.model.common.project.ProjectUserTable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;

@Component
public class SocketService extends GroupSocketService {
    @Autowired
    private MessageMapper messageMapper;
    @Autowired
    private GroupMessageMapper groupMessageMap;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private FriendsMapper friendsMapper;
    @Autowired
    private ProjectClient projectClient;

    @Override
    protected void joinGroup(Integer uid, SocketIOClient socketIOClient) {
        List<ProjectUserTable> projectUserTables = projectClient.listByUser(uid).getData();
        for (ProjectUserTable projectUserTable : projectUserTables) {
            if (!groupMap.containsKey(projectUserTable.getPid())) {
                groupMap.put(projectUserTable.getPid(), new HashSet<>());
            }
            groupMap.get(projectUserTable.getPid()).add(socketIOClient);
        }
    }

    @Override
    protected void leaveGroup(Integer uid) {
        List<ProjectUserTable> projectUserTables = projectClient.listByUser(uid).getData();
        SocketIOClient socketIOClient = super.getClient(uid);
        for (ProjectUserTable projectUserTable : projectUserTables) {
            groupMap.get(projectUserTable.getPid()).remove(socketIOClient);
        }
    }

    @Override
    public void sendGroupMessage(GroupMessage message) {
        if (checkGroupUser(message.getGroupId(), message.getFromUid())) {
            groupMessageMap.insert(message);
            for (SocketIOClient client : super.getGroupClient(message.getGroupId())) {
                try {
                    client.sendEvent("groupMessage", message);
                } catch (NullPointerException ignore) {
                    // 不在线
                }
            }
        }
    }

    @Override
    public void sendMessage(Message message) {
        //1.检查是否为好友
        //2.发送信息
        //3.存储数据库
        boolean isFriends = checkFriend(message.getFromUid(), message.getToUid());
        if (isFriends) {
            messageMapper.insert(message);
            try {
                getClient(message.getToUid()).sendEvent("message", message);
            } catch (NullPointerException ignore) {
                // 不在线
            }
        }
    }

    @Override
    protected boolean checkFriend(Integer uidA, Integer uidB) {
        LambdaQueryWrapper<Friends> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Friends::getUidA, uidA).eq(Friends::getUidB, uidB).eq(Friends::getStatus, 1)
                .or()
                .eq(Friends::getUidA, uidB).eq(Friends::getUidB, uidA).eq(Friends::getStatus, 1);
        return friendsMapper.exists(queryWrapper);
    }

    @Override
    protected boolean checkGroupUser(Long groupId, Integer uid) {
        return projectClient.exist(groupId, uid).getData();
    }

}
